function CountDart( path, filename, initframes )
%COUNTCAR Summary of this function goes here
%   Detailed explanation goes here
global dbdef mkdef

warning('off', 'MATLAB:SingularMatrix');
warning('off', 'MATLAB:singularMatrix');
warning('off', 'MATLAB:nearlySingularMatrix');

fid = fopen(sprintf('%s_punkte.txt', filename), 'w');

GRAPHIC_OUTPUT = 1

startshift = 1;

    darts = [];
    trackDarts = DartTracking();

    movie_name1 = sprintf('%s/%s_Cam1.avi',path,filename);
    movie_name2 = sprintf('%s/%s_Cam2.avi',path,filename);
    mov1 = VideoReader(movie_name1);
    mov2 = VideoReader(movie_name2);

    helper = mov1.read(startshift);
    test = lowLevelImgProcColor(helper);
    init1 = zeros(size(test,1), size(test,2), size(test,3), initframes);
    template1img = im2double(imread('video1_template.jpg'));
    template1img = imresize(template1img, [size(template1img,1)*size(test,1)/size(helper,1) size(template1img,2)*size(test,2)/size(helper,2)]);
    markerDetector = MarkerDetection([1,1], template1img);
    
    helper = mov2.read(startshift);
    test = lowLevelImgProcColor(helper);
    init2 = zeros(size(test,1), size(test,2), size(test,3), initframes);
    template2img = im2double(imread('video2_template.jpg'));
    template2img = imresize(template2img, [size(template2img,1)*size(test,1)/size(helper,1) size(template2img,2)*size(test,2)/size(helper,2)]);
    markerDetector2 = MarkerDetection([1,1], template2img);
    
    % Dartboard 
    % default values
    refdb = imread('board.png');    % reference dart board
    db1def = zeros(initframes, 2);    % dart board width
    db2def = zeros(initframes, 2);
    mk1def = zeros(initframes, 2);     % marker position (field 20|11)
    mk2def = zeros(initframes, 2);
    %-----------

    % <<<--- Initialize --->>>
    for n = startshift : startshift+initframes
        act_frame1 = lowLevelImgProcColor(mov1.read(n));
        act_frame2 = lowLevelImgProcColor(mov2.read(n));
        
        init1(:,:,:,n) = act_frame1(:,:,:);
        init2(:,:,:,n) = act_frame2(:,:,:);
        
        % Dartboard
        %[db1def(n, :)  mk1def(n, :)] = getDartBoard(double(mov1.read(n)));
        %[db2def(n, :)  mk2def(n, :)] = getDartBoard(double(mov2.read(n)));
        helper1 = imresize(double(mov1.read(n)), [256 NaN]);
        helper2 = imresize(double(mov2.read(n)), [256 NaN]);
        
        [db1def(n, :)  mk1def(n, :)] = getDartBoard(helper1);
        [db2def(n, :)  mk2def(n, :)] = getDartBoard(helper2);
        % ---------
    end
    
    % Dartboard
    dbdef(1,:) = median(db1def);
    dbdef(2,:) = median(db2def);
    mkdef(1,:) = median(mk1def);
    mkdef(2,:) = median(mk2def);
    %----------
    
    [img_mean1, img_var1] = initBackgroundModel(init1, initframes);
    [img_mean2, img_var2] = initBackgroundModel(init2, initframes);
    
    
    img_mean_actual1 = img_mean1;   img_var_actual1 = img_var1;
    img_mean_actual2 = img_mean2;   img_var_actual2 = img_var2;
    
    clear init1;    clear init2;
    % <<<--- Initialized --->>>
    
    old_frame1 = act_frame1;
    old_frame2 = act_frame2;
    old_frame1_gray = lowLevelImgProc(act_frame1);
    old_frame2_gray = lowLevelImgProc(act_frame2);
    
    
    test = lowLevelImgProcColor(mov1.read(1));
    init1 = zeros(size(test,1), size(test,2), size(test,3), 25);
    test = lowLevelImgProcColor(mov2.read(1));
    init2 = zeros(size(test,1), size(test,2), size(test,3), 25);
    
    fci_old1 = zeros(size(old_frame1, 1), size(old_frame1, 2));
    fci_old2 = zeros(size(old_frame1, 1), size(old_frame1, 2));
    
    markerDetector =  markerDetector.detectMarker(act_frame1);
    markerDetector2 =  markerDetector2.detectMarker(act_frame2);
    
    state = 0;  %0... no darts are detected 1... darts are detect 2... new dart detected 3... new dart is detected and stopped on dartfield and bg gets initialized
    
    reset_detected = 0;
    new_initframes = 1;
    % <<<--- Count DART --->>>
    for n = (startshift+initframes+1) : mov1.NumberOfFrames
        act_frame1 = lowLevelImgProcColor(mov1.read(n));
        act_frame2 = lowLevelImgProcColor(mov2.read(n));
        
        act_frame1_gray = lowLevelImgProc(act_frame1);
        act_frame2_gray = lowLevelImgProc(act_frame2);
                        
        [ fsi1, fgi1 ] = diffWithBG(act_frame1, img_mean1, img_var1);
        [ fsi2, fgi2 ] = diffWithBG(act_frame2, img_mean2, img_var2);
        
        fci1 = min(fsi1, fgi1);
        fci2 = min(fsi2, fgi2);
        
        %Calculating Blobs
        [ Blobs1 fci1 ] = calculateBlobs( fci1 );
        [ Blobs2 fci2 ] = calculateBlobs( fci2 );
        
        %Calculation new detected objects. Difference between new and old
        %detected objects.
        diff_img1 = im2bw(imabsdiff(act_frame1_gray, old_frame1_gray), 0.1);
        diff_img2 = im2bw(imabsdiff(act_frame2_gray, old_frame2_gray), 0.1);
        
        if(n ~= (startshift+initframes+1)) 
            detect_diff1 = min(imabsdiff(fci1,fci_old1), diff_img1);
            detect_diff2 = min(imabsdiff(fci2,fci_old2), diff_img2);
        else
            detect_diff1 = fci1;
            detect_diff2 = fci2;
        end
        
        [ Blobs1_bgdiff detect_diff1 ] = calculateBlobs( detect_diff1 );
        [ Blobs2_bgdiff detect_diff2 ] = calculateBlobs( detect_diff2 );
        
        
%         figure(98)
%         if(sum(sum(detect_diff1)) > 5)
%             imshow(detect_diff1,[]);
%         end
%         figure(99)
%         if(sum(sum(detect_diff2)) > 5)
%             imshow(detect_diff2,[]);
%         end
        
        fci_old1 = fci1;
        fci_old2 = fci2;
        %-----------------------------------------------------------------
                
        %state 0, 2 or 3
        fci_actual1 = fci1;
        fci_actual2 = fci2;
        
        Blobs_actual1 = struct('Area',{},'BoundingBox',{},'Centroid',{}, 'MajorAxisLength', {}, 'MinorAxisLength', {}, 'Orientation', {}, 'ConvexImage', {});
        Blobs_actual2 = struct('Area',{},'BoundingBox',{},'Centroid',{}, 'MajorAxisLength', {}, 'MinorAxisLength', {}, 'Orientation', {}, 'ConvexImage', {});
        
        new_state = 0;
        switch(state)
        case 0
            Blobs_actual1 = Blobs1;
            Blobs_actual2 = Blobs2;
            trackDarts.m_allow_add_darts = 1;
        case 1
            [ fsi_actual1, fgi_actual1 ] = diffWithBG(act_frame1, img_mean_actual1, img_var_actual1);
            [ fsi_actual2, fgi_actual2 ] = diffWithBG(act_frame2, img_mean_actual2, img_var_actual2);
            fci_actual1 = min(fsi_actual1, fgi_actual1);
            fci_actual2 = min(fsi_actual2, fgi_actual2);
            [ Blobs_actual1 fci_actual1 ] = calculateBlobs( fci_actual1 );
            [ Blobs_actual2 fci_actual2 ] = calculateBlobs( fci_actual2 );
            new_state = 1;
            trackDarts.m_allow_add_darts = 1;
        case 3
            [ fsi_actual1, fgi_actual1 ] = diffWithBG(act_frame1, img_mean_actual1, img_var_actual1);
            [ fsi_actual2, fgi_actual2 ] = diffWithBG(act_frame2, img_mean_actual2, img_var_actual2);
            fci_actual1 = min(fsi_actual1, fgi_actual1);
            fci_actual2 = min(fsi_actual2, fgi_actual2);
            [ Blobs_actual1 fci_actual1 ] = calculateBlobs( fci_actual1 );
            [ Blobs_actual2 fci_actual2 ] = calculateBlobs( fci_actual2 );
            
            if new_initframes == 1
                sprintf('make new backgroundimage')
            end
            
           if new_initframes < 25 
                init1(:,:,:,new_initframes) = act_frame1(:,:,:);
                init2(:,:,:,new_initframes) = act_frame2(:,:,:);
                new_initframes = new_initframes+1;
                new_state = 3;
           else
               [img_mean_actual1, img_var_actual1] = initBackgroundModel(init1, new_initframes);
               [img_mean_actual2, img_var_actual2] = initBackgroundModel(init2, new_initframes);
               new_initframes = 1;
               new_state = 1;
               trackDarts.m_allow_add_darts = 1;
           end
        end
        
%---------------------------------------------------
        % Update Darts in booth videos
        if( size(Blobs_actual1,2) > 0 || size(Blobs_actual2,2) > 0 )
            new_state = 3;
        end
        
        helper_blobs1 = struct('Area',{},'BoundingBox',{},'Centroid',{}, 'MajorAxisLength', {}, 'MinorAxisLength', {}, 'Orientation', {}, 'ConvexImage', {});
        helper_blobs2 = struct('Area',{},'BoundingBox',{},'Centroid',{}, 'MajorAxisLength', {}, 'MinorAxisLength', {}, 'Orientation', {}, 'ConvexImage', {});
        for i = 1 : size(Blobs1_bgdiff,1)
           if(Blobs1_bgdiff(i).BoundingBox(3) > 100 && Blobs1_bgdiff(i).BoundingBox(4) > 100)
               continue;
           end
           helper_blobs1 = [helper_blobs1; Blobs1_bgdiff(i)];
        end
        
        for i = 1 : size(Blobs2_bgdiff,1)
           if(Blobs2_bgdiff(i).BoundingBox(3) < 70 && Blobs2_bgdiff(i).BoundingBox(4) < 70)
               continue;
           end
           helper_blobs2 = [helper_blobs2; Blobs2_bgdiff(i)];
        end
            
        
        if((size(helper_blobs1,2) == 0 ||  size(helper_blobs2,2) == 0) && reset_detected == 1)
            sprintf('if((size(helper_blobs1,2) == 0 ||  size(helper_blobs2,2) == 0) && reset_detected == 1)')
            
            new_state = 3;
            new_initframes = 1;
            reset_detected = 0;
        else
            if(reset_detected == 1)
                
                sprintf('if(reset_detected == 1) trackDarts.m_allow_add_darts = 0;')
                
                new_state = 3;
                trackDarts.m_allow_add_darts = 0;            
            end
        end
        
       trackDarts = trackDarts.updateBGImages(  detect_diff1, detect_diff2, ...
                                                diff_img1, diff_img2, ...
                                                fci1, fci2, ...
                                                fci_actual1, fci_actual2 );
                                
        trackDarts = trackDarts.addNewDarts(n);
        trackDarts = trackDarts.updateRelationBetweenDarts(5);
        trackDarts = trackDarts.updateDarts(n);
        trackDarts.printIntersectionOfNewDart();
        trackDarts = trackDarts.detectMiss()
        trackDarts.printDetectedState(fid);
        trackDarts = trackDarts.deleteDartsDueState(n);
        trackDarts = trackDarts.performReset();
        
        old_frame1 = act_frame1;
        old_frame2 = act_frame2;
        old_frame1_gray = act_frame1_gray;
        old_frame2_gray = act_frame2_gray;
        
        %if state = 1 (miss detected) make a new background model
        if(trackDarts.state_ == 1)
            new_state = 3;
        end
        
        if(trackDarts.state_ == 2)
            sprintf('RESET DETECTED')
            reset_detected = 1;
        end
        
        if(trackDarts.state_ ~= 0)
            trackDarts.m_allow_add_darts = 0;
        end
        
%------------------ DART Board updating -----------------        
        markerDetector = markerDetector.updateMarker(act_frame1);
        markerDetector2 = markerDetector2.updateMarker(act_frame2);
        
        mk(1,:) = markerDetector.m_output_mk;
        mk(2,:) = markerDetector2.m_output_mk; 
               
        db(1,:) = markerDetector.m_point_tracker_out;
        db(2,:) = markerDetector2.m_point_tracker_out;
        
        DB_DELTA = 5;
        dbidx = abs(db-dbdef)>DB_DELTA;     % dartboard
        db(dbidx) = dbdef(dbidx);

        markerDetector.m_point_tracker_out = db(1,:);
        markerDetector2.m_point_tracker_out = db(2,:);
                        
        db1 = db(1,:); db2 = db(2,:);
        mk1 = mk(1,:); mk2 = mk(2,:);

        ratio = diff(db1)/diff(db2);
        cp(1) = mk1(1)+diff(mk1)/2-db1(1);  % center point
        cp(2) = mk2(1)+diff(mk2)/2-db2(1);
        cp(2) = cp(2)*ratio;  
        
        [trackDarts, ip1, ip2] = trackDarts.calcIntersection(db1, db, mk, ratio, cp);
        trackDarts = trackDarts.printScore(fid)        
%------------------ Display images -----------------
        if(GRAPHIC_OUTPUT)            
            hold off;
            
            figure(1);    
           
            subplot(4,2,1)         
            imagesc(act_frame1_gray);
            colormap('gray');  
            
           markerDetector.drawMarker();
           markerDetector.drawMarkerOutside();
                        
            trackDarts.drawNewDartsCam1();
            trackDarts.drawAllDartsCam1();
            title('Cam 1');
        
            subplot(4,2,2)
            imagesc(act_frame2_gray);
            title('Cam 2');
            colormap('gray');  

           markerDetector2.drawMarker();
           markerDetector2.drawMarkerOutside();
            
            trackDarts.drawNewDartsCam2();
            trackDarts.drawAllDartsCam2();
        
            subplot(4,2,3)
            %imagesc(fci1);
            imagesc(trackDarts.bg1_mask_);
            colormap('gray');  
        
            title('Cam 1');
            subplot(4,2,4)
            %imagesc(fci2);
            imagesc(trackDarts.bg2_mask_);
            title('Cam 2');
            colormap('gray');  
        
            subplot(4,2,5)
            %imagesc(fci_actual1);
            imagesc(trackDarts.actbg1_mask_);
            colormap('gray');  
        
            title('Cam 1');
            subplot(4,2,6)
            %imagesc(fci_actual2);
            imagesc(trackDarts.actbg2_mask_);
            title('Cam 2');
            colormap('gray');  
        
            title('Cam 1');
            subplot(4,2,7)
            %imagesc(detect_diff1);
            imagesc(detect_diff1);
            title('Cam 2');
            colormap('gray');  
            
            title('Cam 2');
            subplot(4,2,8)
            %imagesc(detect_diff2);
            imagesc(detect_diff2);
            title('Cam 2');
            colormap('gray');  
        
%             title('Cam 1');
%             subplot(5,2,9)
%             %imagesc(diff_img1);
%             imagesc(diff_img1);
%             title('Cam 2');
%             colormap('gray');  
%         
%             title('Cam 2');
%             subplot(6,2,10)
%             %imagesc(diff_img2);
%             imagesc(diff_img2);
%             title('Cam 2');
%             colormap('gray');
            hold off;
             
            hold on;
        end
        
        %UpdateMeanAndVar updates only the parts, where no foreground
        %object was detected. 
        [ img_mean1, img_var1 ] = UpdateMeanAndVar( act_frame1, img_mean1, img_var1, fci1);
        [ img_mean2, img_var2 ] = UpdateMeanAndVar( act_frame2, img_mean2, img_var2, fci2);
        
        if(state == 1)
            [ img_mean_actual1, img_var_actual1 ] = UpdateMeanAndVar( act_frame1, img_mean_actual1, img_var_actual1, fci_actual1);
            [ img_mean_actual2, img_var_actual2 ] = UpdateMeanAndVar( act_frame2, img_mean_actual2, img_var_actual2, fci_actual2);
        end
        
        trackDarts = trackDarts.frameUpdate();
        
        n
        state = new_state
        sprintf('****************************************')
    end
    % <<<--- DART Count --->>>
    
    fclose(fid);
end

